// Copyright 2022 a.o.smith ALL Rights Reserved
package com.liuxinlong.modules.specialist.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.liuxinlong.api.WeChatMessageInterface;
import com.liuxinlong.common.AosException;
import com.liuxinlong.common.ExcelData;
import com.liuxinlong.common.SnowFlake;
import com.liuxinlong.constant.SystemConstants;
import com.liuxinlong.constant.ThreadLocalConstants;
import com.liuxinlong.constant.TimeFormatConstants;
import com.liuxinlong.enums.DifficultyStatusEnum;
import com.liuxinlong.enums.FileBusinessTypeEnum;
import com.liuxinlong.enums.MessageContentTypeEnum;
import com.liuxinlong.enums.MessagePushBusinessEnum;
import com.liuxinlong.enums.NotificationSourceEnum;
import com.liuxinlong.enums.ExpertProjectLevelEnum;
import com.liuxinlong.enums.ReturnCodes;
import com.liuxinlong.modules.dao.DepartmentDao;
import com.liuxinlong.modules.dao.DifficultyDao;
import com.liuxinlong.modules.dao.DifficultyPlanDao;
import com.liuxinlong.modules.dao.ExpertDao;
import com.liuxinlong.modules.dao.ExpertProjectDao;
import com.liuxinlong.modules.dao.FileManageDao;
import com.liuxinlong.modules.dao.NotificationDao;
import com.liuxinlong.modules.dao.ParameterDao;
import com.liuxinlong.modules.dao.ProjectNewsDao;
import com.liuxinlong.modules.dao.RoleDao;
import com.liuxinlong.modules.dao.UserDao;
import com.liuxinlong.modules.dao.UserRoleRelationDao;
import com.liuxinlong.modules.entity.Difficulty;
import com.liuxinlong.modules.entity.DifficultyPlan;
import com.liuxinlong.modules.entity.ExpertProject;
import com.liuxinlong.modules.entity.FileManage;
import com.liuxinlong.modules.entity.MessageConfiguration;
import com.liuxinlong.modules.entity.Notification;
import com.liuxinlong.modules.entity.ProjectNews;
import com.liuxinlong.modules.entity.SystemParameter;
import com.liuxinlong.modules.entity.User;
import com.liuxinlong.modules.entity.UserDepartment;
import com.liuxinlong.modules.entity.UserRole;
import com.liuxinlong.modules.entity.UserRoleRelation;
import com.liuxinlong.modules.out.dto.ProjectDto;
import com.liuxinlong.modules.specialist.service.DifficultyService;
import com.liuxinlong.modules.specialist.service.SpecialistProjectService;
import com.liuxinlong.modules.system.service.FileManageService;
import com.liuxinlong.push.MessagePushService;
import com.liuxinlong.utils.ExcelUtils;
import com.liuxinlong.utils.IPUtils;
import com.liuxinlong.utils.ObjectUtils;
import com.liuxinlong.utils.PdfUtils;
import com.liuxinlong.utils.ThreadlocalUtils;
import com.liuxinlong.utils.TimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartRequest;
import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 项目信息服务层实现类
 *
 * @author liuxinlong@hotwater.com.cn
 * @version 1.0.0
 * @since 2023年3月8日
 */
@Slf4j
@Service
public class SpecialistProjectServiceImpl implements SpecialistProjectService {

    @Autowired
    private ExpertProjectDao projectDao;

    @Autowired
    private UserDao userDao;

    @Autowired
    private ExpertDao expertDao;

    @Autowired
    private DepartmentDao departmentDao;

    @Autowired
    private DifficultyDao difficultyDao;

    @Autowired
    private ProjectNewsDao projectNewsDao;

    @Autowired
    private UserRoleRelationDao userRoleRelationDao;

    @Autowired
    private FileManageDao fileManageDao;

    @Autowired
    private ParameterDao parameterDao;

    @Autowired
    private NotificationDao notificationDao;

    @Autowired
    private MessagePushService messagePushService;

    @Autowired
    private WeChatMessageInterface weChatMessageInterface;

    @Autowired
    private RoleDao roleDao;

    @Autowired
    private FileManageService fileManageService;

    @Autowired
    private DifficultyService difficultyService;

    @Autowired
    private DifficultyPlanDao difficultyPlanDao;

    @Override
    public List<Map<String, Object>> pageProjectInfo(Map<String, Object> queryParam) {
        int startNum = (int) queryParam.get("startNum");
        List<ExpertProject> originList = projectDao.pageProjectList(queryParam);
        return completeResult(originList, startNum);
    }

    @Override
    public int getProjectCount(Map<String, Object> queryParam) {
        return projectDao.getProjectCount(queryParam);
    }

    @Override
    @Transactional
    public Map<String, Object> addProjectInfo(ExpertProject project, ProjectDto outProject) {
        ExpertProject oldInfo = projectDao.getProjectBySn(project.getProjectSn());
        if (!ObjectUtils.isEmpty(oldInfo)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "新增失败，项目已存在！");
        }
        project.setProjectName(outProject.getProjectName());
        project.setProjectLevel(ExpertProjectLevelEnum.getValueByName(outProject.getProjectLevel()));
        project.setStartDate(outProject.getStartDate());
        project.setEndDate(outProject.getEndDate());

        Map<String, Object> resultMap = new HashMap<>();
        if (StringUtils.isEmpty(project.getDepartment()) || StringUtils.isEmpty(project.getProjectManager()) || project.getStatus() == 0) {
            List<UserDepartment> depList = departmentDao.getDepartmentListByName(outProject.getDepartment());
            if (ObjectUtils.isEmpty(depList) || depList.size() > 1) {
                resultMap.put("department", outProject.getDepartment());
            } else {
                project.setDepartment(depList.get(0).getId());
            }
            List<User> userList = userDao.getUserListByName(outProject.getProjectManager());
            if (ObjectUtils.isEmpty(userList) || userList.size() > 1) {
                resultMap.put("projectManager", outProject.getProjectManager());
            } else {
                project.setProjectManager(userList.get(0).getId());
            }
            resultMap.put("status", outProject.getStatus());
        }
        project.setProjectType(outProject.getProjectType());
        if (ObjectUtils.isEmpty(resultMap)) {
            String id = SnowFlake.nextIdStr();
            project.setId(id);
            User currentUser = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
            if (ObjectUtils.isEmpty(currentUser)) {
                throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "当前用户不存在");
            }
            String userId = currentUser.getId();
            project.setCreateUser(userId);
            projectDao.insert(project);
//            ProjectNews projectNews = new ProjectNews();
//            projectNews.setId(SnowFlake.nextIdStr());
//            projectNews.setContent(currentUser.getName() + "创建了项目【" + project.getProjectName() + "】");
//            projectNews.setCreateTime(TimeUtils.getDate(TimeFormatConstants.YYYY_MM_DD_HH_MM_SS));
//            projectNews.setCreateUser(userId);
//            projectNewsDao.insert(projectNews);
            if (StringUtils.isEmpty(project.getAppointedExpert()) && StringUtils.isEmpty(project.getDivideExpert())) {
                return resultMap;
            }
            List<String> expertList = new ArrayList<>();
            List<String> appointedExpertList = StringUtils.isEmpty(project.getAppointedExpert()) ? new ArrayList<>() : Arrays.asList(project.getAppointedExpert().split(","));
            expertList.addAll(appointedExpertList);
            List<String> divideExpertList = StringUtils.isEmpty(project.getDivideExpert()) ? new ArrayList<>() : Arrays.asList(project.getDivideExpert().split(","));
            expertList.addAll(divideExpertList);

            if (!expertList.isEmpty()) {
                String createTime = TimeUtils.getDate(TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
                User current = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
                Map<String, Map<String, String>> userMap = userDao.getUserMap();
                List<Notification> notificationList = new ArrayList<>();
                List<ProjectNews> projectNewsList = new ArrayList<>();
                String content = current.getName() + " 邀请您加入项目 【" + oldInfo.getProjectName() + "】 ";
                for (String expert : expertList) {
                    if (!userMap.containsKey(expert)) {
                        continue;
                    }
                    Notification notification = new Notification();
                    notification.setId(SnowFlake.nextIdStr());
                    notification.setCreateTime(createTime);
                    notification.setCreateUser(current.getId());
                    notification.setSourceId(project.getId());
                    notification.setContent(content);
                    notification.setDealUser(expert);
                    notification.setSourceType(NotificationSourceEnum.EXPERT_MODULE.getValue());
                    notificationList.add(notification);
                    Map<String, String> contentMap = new HashMap<>();
                    contentMap.put("title", "您有一条新消息待查看");
                    contentMap.put("description", notification.getContent());
                    String contentStr = JSON.toJSONString(contentMap);
                    Map<String, String> targetUser = userMap.get(expert);
                    messagePushService.pushMessage(contentStr, targetUser.get("sn"));
                    ProjectNews projectNews = new ProjectNews();
                    projectNews.setCreateUser(userId);
                    projectNews.setCreateTime(createTime);
                    projectNews.setId(SnowFlake.nextIdStr());
                    projectNews.setContent("专家 " + targetUser.get("name") + " 被【" + project.getProjectName() + "】项目选中");
                    projectNewsList.add(projectNews);
                }
                notificationDao.insertBatch(notificationList);
                projectNewsDao.insertBatch(projectNewsList);
                MessageConfiguration messageConfiguration = new MessageConfiguration();
                messageConfiguration.setBusinessType(MessagePushBusinessEnum.INTERACTIVE.getValue());
                messageConfiguration.setContent(content);
                messageConfiguration.setContentType(MessageContentTypeEnum.TEXT_CARD.getValue());
                weChatMessageInterface.pushMessage(expertList, null, messageConfiguration, createTime);
                expertDao.updateProjectCount(expertList);
            }
        } else {
            resultMap.put("project", project);
        }

        return resultMap;
    }

    @Override
    @Transactional
    public void updateProjectInfo(ExpertProject project) {
        User currentUser = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        if (ObjectUtils.isEmpty(currentUser)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "用户登陆状态异常！");
        }
        ExpertProject oldInfo = projectDao.selectById(project.getId());
        if (ObjectUtils.isEmpty(oldInfo)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "修改失败，原项目信息不存在！");
        }
        oldInfo.setProjectMember(project.getProjectMember());
        if (!StringUtils.equals(project.getAppointedExpert(), oldInfo.getAppointedExpert()) || !StringUtils.equals(project.getDivideExpert(), oldInfo.getDivideExpert())) {
            List<String> oldList = new ArrayList<>();
            List<String> newList = new ArrayList<>();
            List<String> oldAList = StringUtils.isEmpty(oldInfo.getAppointedExpert()) ? new ArrayList<>() : Arrays.asList(oldInfo.getAppointedExpert().split(","));
            oldList.addAll(oldAList);
            List<String> newAList = StringUtils.isEmpty(project.getAppointedExpert()) ? new ArrayList<>() : Arrays.asList(project.getAppointedExpert().split(","));
            newList.addAll(newAList);
            List<String> oldDList = StringUtils.isEmpty(oldInfo.getDivideExpert()) ? new ArrayList<>() : Arrays.asList(oldInfo.getDivideExpert().split(","));
            oldList.addAll(oldDList);
            List<String> newDList = StringUtils.isEmpty(project.getDivideExpert()) ? new ArrayList<>() : Arrays.asList(project.getDivideExpert().split(","));
            newList.addAll(newDList);
            List<String> sameList = newList.stream().filter(p -> oldList.contains((String) p)).collect(Collectors.toList());
            newList.removeAll(sameList);
            oldList.removeAll(sameList);
            if (!ObjectUtils.isEmpty(newList)) {
                String createTime = TimeUtils.getDate(TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
                Map<String, Map<String, String>> userMap = userDao.getUserMap();
                Map<String,Map<String,String>> expertMap = expertDao.getExpertMap();
                List<Notification> notificationList = new ArrayList<>();
                List<ProjectNews> projectNewsList = new ArrayList<>();
                String content = currentUser.getName() + " 邀请您加入项目 【" + oldInfo.getProjectName() + "】 ";
                for (String expert : newList) {
                    if (!userMap.containsKey(expert)) {
                        continue;
                    }
                    Notification notification = new Notification();
                    notification.setId(SnowFlake.nextIdStr());
                    notification.setCreateTime(createTime);
                    notification.setCreateUser(currentUser.getId());
                    notification.setSourceId(project.getId());
                    notification.setContent(content);
                    notification.setDealUser(expert);
                    notification.setSourceType(NotificationSourceEnum.EXPERT_MODULE.getValue());
                    notificationList.add(notification);
                    Map<String, String> contentMap = new HashMap<>();
                    contentMap.put("title", "您有一条新消息待查看");
                    contentMap.put("description", notification.getContent());
                    String contentStr = JSON.toJSONString(contentMap);
                    Map<String, String> targetUser = userMap.get(expert);
                    messagePushService.pushMessage(contentStr, targetUser.get("sn"));
                    ProjectNews projectNews = new ProjectNews();
                    projectNews.setCreateUser(currentUser.getId());
                    projectNews.setCreateTime(createTime);
                    projectNews.setId(SnowFlake.nextIdStr());
                    projectNews.setContent("专家 " + targetUser.get("name") + " 被【" + oldInfo.getProjectName() + "】项目选中");
                    projectNewsList.add(projectNews);
                }
                notificationDao.insertBatch(notificationList);
                projectNewsDao.insertBatch(projectNewsList);
                MessageConfiguration messageConfiguration = new MessageConfiguration();
                messageConfiguration.setBusinessType(MessagePushBusinessEnum.INTERACTIVE.getValue());
                messageConfiguration.setContent(content);
                messageConfiguration.setContentType(MessageContentTypeEnum.TEXT_CARD.getValue());
                weChatMessageInterface.pushMessage(newList, null, messageConfiguration, createTime);
                expertDao.updateProjectCount(newList);
            } else {
                List list = newAList.stream().filter(p -> oldAList.contains(p)).collect(Collectors.toList());
            }
            if (!ObjectUtils.isEmpty(oldList)) {
                String createTime = TimeUtils.getDate(TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
                Map<String, Map<String, String>> userMap = userDao.getUserMap();
                List<Notification> notificationList = new ArrayList<>();
                String content =  " 您已被" + currentUser.getName() +"移出项目 【" + oldInfo.getProjectName() + "】 ";
                for (String expert : oldList) {
                    if (!userMap.containsKey(expert)) {
                        continue;
                    }
                    Notification notification = new Notification();
                    notification.setId(SnowFlake.nextIdStr());
                    notification.setCreateTime(createTime);
                    notification.setCreateUser(currentUser.getId());
                    notification.setSourceId(project.getId());
                    notification.setContent(content);
                    notification.setDealUser(expert);
                    notification.setSourceType(NotificationSourceEnum.EXPERT_MODULE.getValue());
                    notificationList.add(notification);
                    Map<String, String> contentMap = new HashMap<>();
                    contentMap.put("title", "您有一条新消息待查看");
                    contentMap.put("description", notification.getContent());
                    String contentStr = JSON.toJSONString(contentMap);
                    Map<String, String> targetUser = userMap.get(expert);
                    messagePushService.pushMessage(contentStr, targetUser.get("sn"));
                }
                notificationDao.insertBatch(notificationList);
                MessageConfiguration messageConfiguration = new MessageConfiguration();
                messageConfiguration.setBusinessType(MessagePushBusinessEnum.INTERACTIVE.getValue());
                messageConfiguration.setContent(content);
                messageConfiguration.setContentType(MessageContentTypeEnum.TEXT_CARD.getValue());
                weChatMessageInterface.pushMessage(oldList, null, messageConfiguration, createTime);
                expertDao.reduceProjectCount(oldList);
            } else {

            }
        }
        oldInfo.setAppointedExpert(project.getAppointedExpert());
        oldInfo.setDivideExpert(project.getDivideExpert());
        oldInfo.setEndDate(project.getEndDate());
        oldInfo.setStatus(project.getStatus());
        projectDao.updateById(oldInfo);

    }

    @Override
    @Transactional
    public void deleteProjectInfo(String id) {
        User currentUser = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        if (ObjectUtils.isEmpty(currentUser)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "用户登陆状态异常！");
        }
        ExpertProject project = projectDao.selectById(id);
        if (ObjectUtils.isEmpty(project)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "项目不存在！");
        }
        List<UserRoleRelation> userRoleRelationList = userRoleRelationDao.queryRelationByUserId(currentUser.getId());
        UserRole manageRole = roleDao.getRoleBySn("J017");
        List<UserRoleRelation> existList;
        if (ObjectUtils.isEmpty(manageRole)) {
            existList = new ArrayList<>();
            if (StringUtils.equals(currentUser.getId(), project.getCreateUser())) {
                UserRoleRelation userRoleRelation = new UserRoleRelation();
                userRoleRelation.setUserId(currentUser.getId());
                existList.add(userRoleRelation);
            }
        } else {
            existList = userRoleRelationList.stream().filter(relation -> StringUtils.equals(relation.getRoleId(), manageRole.getId())).collect(Collectors.toList());
        }
        if (existList.isEmpty()) {
            return;
        }
        project.setStatus(DifficultyStatusEnum.REPEALED.getValue());
        project.setUpdateUser(currentUser.getId());
        String currentTime = TimeUtils.getDate(TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
        project.setUpdateTime(currentTime);
        projectDao.updateById(project);
        List<String> expertList = new ArrayList<>();
        List<String> appointedExpertList = Arrays.asList(project.getAppointedExpert().split(","));
        expertList.addAll(appointedExpertList);
        List<String> divideExpertList = Arrays.asList(project.getDivideExpert().split(","));
        expertList.addAll(divideExpertList);
        expertDao.reduceProjectCount(expertList);

        // 更新问题点信息
        Map<String, Object> queryDifParam = new HashMap<>();
        queryDifParam.put("startNum", 0);
        queryDifParam.put("pageSize", 10000);
        queryDifParam.put("projectId", id);
        List<Difficulty> difficultyList = difficultyDao.pageDifficultyList(queryDifParam);
        List<Difficulty> newDifficultyList = new ArrayList<>();
        List<String> solveList = new ArrayList<>();
        List<String> riskList = new ArrayList<>();
        for (Difficulty difficulty : difficultyList) {
            difficulty.setUpdateTime(currentTime);
            difficulty.setUpdateUser(currentUser.getId());
            if (difficulty.getPointType() == 1 && difficulty.getStatus() == DifficultyStatusEnum.FINISHED.getValue()) {
                solveList.add(difficulty.getId());
            }
            if (difficulty.getPointType() == 2) {
                List<String> assistExpert = Arrays.asList(difficulty.getAssistExpert().split(","));
                riskList.addAll(assistExpert);
            }
            difficulty.setStatus(DifficultyStatusEnum.REPEALED.getValue());
            newDifficultyList.add(difficulty);
        }
        if (!ObjectUtils.isEmpty(newDifficultyList)) {
            difficultyDao.updateBatchById(newDifficultyList);
        }
        // 更新风险点
        if (!ObjectUtils.isEmpty(riskList)) {
            expertDao.reduceRiskCount(riskList);
        }

        // 更新解决方案信息
        Map<String, Object> queryPlanParam = new HashMap<>();
        queryPlanParam.put("startNum", 0);
        queryPlanParam.put("pageSize", 10000);
        queryPlanParam.put("projectId", id);
        List<DifficultyPlan> difficultyPlanList = difficultyPlanDao.pageDifficultyPlanList(queryPlanParam);
        List<DifficultyPlan> newPlanList = new ArrayList<>(difficultyPlanList.size());
        Set<String> solveExpertSet = new HashSet<>();
        for (DifficultyPlan plan : difficultyPlanList) {
            plan.setStatus(1);
            plan.setUpdateTime(currentTime);
            plan.setUpdateUser(currentUser.getId());
            newPlanList.add(plan);
            if (solveList.contains(plan.getDifficultyId())) {
                solveExpertSet.add(plan.getExpertId());
            }
        }
        if (!ObjectUtils.isEmpty(newPlanList)) {
            difficultyPlanDao.updateBatchById(newPlanList);
        }

        if (!ObjectUtils.isEmpty(solveExpertSet)) {
            expertDao.reduceSolveCount(new ArrayList<>(solveExpertSet));
        }
    }

    @Override
    public void exportProjectList(HttpServletResponse response) {
        Map<String, Map<String, String>> userMap = userDao.getUserMap();
        Map<String, Map<String, String>> departmentMap = departmentDao.getDepartmentMap();
        ExcelData data = new ExcelData();
        data.setFileName("项目信息清单导出excel.xlsx");
        List<ExpertProject> questionList = projectDao.getProjectList();
        String[] head = {"序号", "项目号", "项目名称", "项目经理", "项目等级", "项目状态", "项目类型", "责任部门", "项目成员", "专家成员"};
        data.setHead(head);
        String[][] dataList = new String[questionList.size()][head.length];
        int index = 0;
        for (ExpertProject item : questionList) {
            dataList[index][0] = String.valueOf(index + 1);
            dataList[index][1] = item.getProjectSn();
            dataList[index][2] = item.getProjectName();
            dataList[index][3] = userMap.containsKey(item.getProjectManager()) ? userMap.get(item.getProjectManager()).get("name") : "";
            dataList[index][4] = ExpertProjectLevelEnum.getNameByValue(item.getProjectLevel());
            dataList[index][5] = DifficultyStatusEnum.getNameByValue(item.getStatus());
            dataList[index][6] = item.getProjectType();
            dataList[index][7] = departmentMap.containsKey(item.getDepartment()) ? departmentMap.get(item.getDepartment()).get("name") : "";
            List<String> memberList = Arrays.asList(item.getProjectMember().split(","));
            String memberNames = "";
            if (!memberList.isEmpty()) {
                List<String> memberNameList = new ArrayList<>();
                for (String member : memberList) {
                    if (StringUtils.isEmpty(member)) {
                        continue;
                    }
                    memberNameList.add(userMap.containsKey(member) ? userMap.get(member).get("name") : member);
                }
                memberNames = StringUtils.strip(memberNameList.toString(), "[]");
            }
            dataList[index][8] = memberNames;
            List<String> expertList = new ArrayList<>();
            List<String> appointedExpertList = Arrays.asList(item.getAppointedExpert().split(","));
            expertList.addAll(appointedExpertList);
            List<String> divideExpertList = Arrays.asList(item.getDivideExpert().split(","));
            expertList.addAll(divideExpertList);
            String expertNames = "";
            if (!expertList.isEmpty()) {
                List<String> expertNameList = new ArrayList<>();
                for (String expert : expertList) {
                    if (StringUtils.isEmpty(expert)) {
                        continue;
                    }
                    expertNameList.add(userMap.containsKey(expert) ? userMap.get(expert).get("name") : expert);
                }
                expertNames = StringUtils.strip(expertNameList.toString(), "[]");
            }
            dataList[index][9] = expertNames;
            index++;
        }
        data.setData(Arrays.asList(dataList));
        ExcelUtils.exportExcel(response, data);
    }

    @Override
    public void exportProjectInfo(String id, HttpServletResponse response) {
        ExpertProject project = projectDao.selectById(id);
        if (ObjectUtils.isEmpty(project)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "导出失败，项目不存在！");
        }
        Map<String, Object> map = ObjectUtils.object2Map(project);
        // 项目经理
        User manager = userDao.selectById(project.getProjectManager());
        map.put("projectManagerName", manager.getName());
        // 责任部门
        UserDepartment department = departmentDao.selectById(project.getDepartment());
        map.put("departmentName", department.getName());
        map.put("statusName", DifficultyStatusEnum.getNameByValue(project.getStatus()));
        Map<String, Object> queryDifficultyParam = new HashMap<>();
        queryDifficultyParam.put("projectId", id);
//        queryDifficultyParam.put("pointType", 1);
        queryDifficultyParam.put("startNum", 0);
        queryDifficultyParam.put("pageSize", 10000);
        List<Map<String, Object>> allDifList = difficultyService.pageDifficultyInfo(queryDifficultyParam);
        List<Map<String, Object>> difficultyList = allDifList.stream().filter(item -> (int) item.get("pointType") == 1).collect(Collectors.toList());
        List<Map<String, Object>> riskList = allDifList.stream().filter(item -> (int) item.get("pointType") == 2).collect(Collectors.toList());
        map.put("difficultyList", difficultyList);
        map.put("riskList", riskList);
        List<Map<String, Object>> difficultyPlanList = difficultyService.pageDifficultyPlanInfo(queryDifficultyParam);
        map.put("difficultyPlanList", difficultyPlanList);
        PdfUtils.generatePDFDoc("project.pdf", response, map,1);
        String fileName = "test.pdf";
        String path = "pdf/";

//        try {
//            // 目标路径
//            File file = new File(path);
//            // 如果文件目录不存在，就执行创建
//            if (!file.isDirectory()) {
//                file.mkdirs();
//            }
//
//            //创建文档，设置页面大小、左右上下边距
//            Document document = new Document();
//
//            //处理中文显示问题，使用资源字体
//            BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H",BaseFont.NOT_EMBEDDED);
//
//            Font dateTitle = new Font(bfChinese,7,Font.NORMAL);
//            Font title = new Font(bfChinese,12,Font.BOLD);//文字加粗
//            Font textFont = new Font(bfChinese,7,Font.NORMAL);//文字正常
//
//            //给出输出路径
//            PdfWriter.getInstance(document, new FileOutputStream(path+fileName));
//
//            //打开文档
//            document.open();
//
//            //标题
//            PdfPTable tableTitle = new PdfPTable(3);
//
//            PdfPTable codeTitle = new PdfPTable(1);
//            //生成一个7列的表格
//            PdfPTable table = new PdfPTable(7);
//
//            //定义每个单元格的宽度
//            float[] widthsHeaderTitle = {1f,1f,1f};
//            float[] widthsCodeTitle = {1f};
//            float[] widthsHeader = {1f,1f,1f,1f,1f,1f,2f};
//
//            float lineHeight = (float)20.0;
//
//            //设置表格每一格的宽度
//            tableTitle.setWidths(widthsHeaderTitle);
//            codeTitle.setWidths(widthsCodeTitle);
//            table.setWidths(widthsHeader);
//
//            //设置表格总体宽度
//            tableTitle.setWidthPercentage(100);
//            codeTitle.setWidthPercentage(100);
//            table.setWidthPercentage(100);
//
//            int colSpan = 1;
//
//            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//            Date date = new Date(System.currentTimeMillis());
//            //添加标题
//            PdfUtils.createTableCellLeft("导出人：行如火", textFont, tableTitle, lineHeight, colSpan);
//            PdfUtils.createTableCellCenter("确认出差记录表", title, tableTitle, lineHeight, colSpan);
//            PdfUtils.createTableCellRight(formatter.format(date), dateTitle, tableTitle, lineHeight, colSpan);
//
//            document.add(tableTitle);
//            PdfUtils.createTableCellRight("功能码： XXXXXXXXX",textFont, codeTitle, lineHeight, colSpan);
//            document.add(codeTitle);
//            document.add(new Paragraph("\n"));
//
//            String[] array = {"报表生成日期 ","状态 ", "经办人员 ", "提交时间 ","复核人员 ", "复核时间 ", "情况补充 "};
//            for (String s : array) {
//                PdfUtils.createTableCell(s, textFont, table, lineHeight, colSpan);
//            }
//            List<Map<String, Object>> dataResult = PdfUtils.getResult();
//
//            for (Map<String, Object> map : dataResult) {
//                String dataTime = map.get("dateTime") != null?map.get("dateTime").toString():"0";
//                String status = "0";
//                if (null != map.get("status")) {
//                    if ("0".equals(map.get("status"))) {
//                        status = "待确认";
//                    }
//                    if ("1".equals(map.get("status"))) {
//                        status = "待复核";
//                    }
//                    if ("2".equals(map.get("status"))) {
//                        status = "已复核";
//                    }
//                }
//                String creator = map.get("creator") != null?map.get("creator").toString():"0";
//                String createTime = map.get("createTime") != null?map.get("createTime").toString():"0";
//                String updator = map.get("updator") != null?map.get("updator").toString():"0";
//                String updateTime = map.get("updateTime") != null?map.get("updateTime").toString():"0";
//                String description = map.get("description") != null?map.get("description").toString():"0";
//
//                PdfUtils.createTableCell(dataTime, textFont, table, lineHeight, colSpan);
//                PdfUtils.createTableCell(status, textFont, table, lineHeight, colSpan);
//                PdfUtils.createTableCell(creator, textFont, table, lineHeight, colSpan);
//                PdfUtils.createTableCell(createTime, textFont, table, lineHeight, colSpan);
//                PdfUtils.createTableCell(updator, textFont, table, lineHeight, colSpan);
//                PdfUtils.createTableCell(updateTime, textFont, table, lineHeight, colSpan);
//                PdfUtils.createTableCell(description, textFont, table, lineHeight, colSpan);
//            }
//            document.add(table);
//            document.close();
//
//        } catch (DocumentException e) {
//            e.printStackTrace();
//        } catch (FileNotFoundException e) {
//            e.printStackTrace();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//        File targetFile = new File(fileName);

    }

    @Override
    public List<Map<String, Object>> queryMemberInfos(String id) {
        ExpertProject project = projectDao.selectById(id);
        if (ObjectUtils.isEmpty(project)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "项目信息不存在！");
        }
        List<Map<String, Object>> dataList = new ArrayList<>();
        List<String> allMemberList = new ArrayList<>();
        List<String> memberList = Arrays.asList(project.getProjectMember().split(","));
        allMemberList.add(project.getProjectManager());
        allMemberList.addAll(memberList);
        Map<String, Map<String, String>> userMap = userDao.getUserPictureMap();
        String currentIp = IPUtils.getCurrentIp();
        for (String member : allMemberList) {
            if (userMap.containsKey(member)) {
                Map<String, String> data = userMap.get(member);
                Map<String, Object> memberMap = new HashMap<>();
                memberMap.put("id", data.get("id"));
                memberMap.put("name", data.get("name"));
                memberMap.put("image", data.containsKey("portrait") ? data.get("filePath").replace("upload", "http:\\\\" + currentIp + ":8090\\preview\\upload") : "");
                memberMap.put("memberType", StringUtils.equals(member, project.getProjectManager()) ? 1 : 2);
                dataList.add(memberMap);
            }
        }
        return dataList;
    }

    @Override
    public Map<String, Object> queryProjectSummary() {
        Map<String, Object> queryParam = new HashMap<>();
        return projectDao.queryProjectSummary(queryParam);
    }

    @Override
    public Map<String, Object> queryProjectDetail(String id) {
        Map<String, Object> detailMap = new HashMap<>();

        // 项目信息
        ExpertProject project = projectDao.selectById(id);
        if (ObjectUtils.isEmpty(project)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "项目不存在！");
        }
        List<String> membweList = Arrays.asList(project.getProjectMember().split(","));
        detailMap.put("memberNum", membweList.size());

        // 难点信息
        Map<String, Object> difficultyMap = difficultyDao.getDifficultySummary(id);
        long totalTask = (long) difficultyMap.get("allNum");
        long finishTask = (long) difficultyMap.get("finishNum");
        long overTask = (long) difficultyMap.get("overNum");
        detailMap.put("ongoingTask", totalTask - finishTask);
        detailMap.put("totalTask", totalTask);
        detailMap.put("overTime", overTask);

        // 文件信息
        Map<String, Object> queryFileParam = new HashMap<>();
        queryFileParam.put("businessId", id);
        queryFileParam.put("businessType", FileBusinessTypeEnum.PROJECT_FILE.getValue());
        int fileCount = fileManageDao.getFileManageCount(queryFileParam);
        detailMap.put("fileNum", fileCount);

        // 剩余时间
        String leftDay;
        if (project.getStatus() == DifficultyStatusEnum.FINISHED.getValue() || project.getStatus() == DifficultyStatusEnum.REPEALED.getValue()) {
            leftDay = DifficultyStatusEnum.getNameByValue(project.getStatus());
        } else {
            Date deadline = TimeUtils.formatTime(project.getEndDate(), TimeFormatConstants.YYYY_MM_DD);
            leftDay = TimeUtils.fromDeadlineDays(deadline);
        }
        detailMap.put("leftDay", leftDay);
        return detailMap;
    }

    @Override
    public void updateProjectMemberInfo(String projectId, String memberId, int operateType) {
        ExpertProject projectInfo = projectDao.selectById(projectId);
        if (ObjectUtils.isEmpty(projectInfo)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "修改失败，项目不存在！");
        }
        if (operateType == 1) {
            String projectMembers = projectInfo.getProjectMember();
            if (StringUtils.isEmpty(projectMembers)) {
                projectInfo.setProjectMember(memberId);
            } else {
                List<String> projectMemberList = Arrays.asList(projectMembers.split(","));
                if (projectMemberList.contains(memberId)) {
                    throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "添加失败，项目成员已存在！");
                }
                List<String> newMemberList = new ArrayList<>();
                newMemberList.addAll(projectMemberList);
                newMemberList.add(memberId);
                projectInfo.setProjectMember(StringUtils.deleteWhitespace(StringUtils.strip(newMemberList.toString(), "[]")));
            }
        } else {
            String projectMembers = projectInfo.getProjectMember();
            if (StringUtils.isEmpty(projectMembers)) {
                return;
            }
            List<String> projectMemberList = Arrays.asList(projectMembers.split(","));
            if (!projectMemberList.contains(memberId)) {
                throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "移除失败，项目成员不存在！");
            }
            List<String> newMemberList = new ArrayList<>();
            newMemberList.addAll(projectMemberList);
            newMemberList.remove(memberId);
            if (ObjectUtils.isEmpty(newMemberList)) {
                projectInfo.setProjectMember("");
            } else {
                projectInfo.setProjectMember(StringUtils.deleteWhitespace(StringUtils.strip(newMemberList.toString(), "[]").trim()));
            }
        }
        projectDao.updateById(projectInfo);
    }

    @Override
    public void addFileInfos(MultipartRequest multipartRequest) {
        String projectId = ((StandardMultipartHttpServletRequest) multipartRequest).getParameterMap().get("projectId")[0];
        List<Map<String, Object>> dataList = fileManageService.batchUploadFileLocal(multipartRequest, FileBusinessTypeEnum.PROJECT_FILE.getValue());
        if (ObjectUtils.isEmpty(dataList)) {
            return;
        }
        String[] fileList = dataList.stream().map(map -> (String) map.get("id")).collect(Collectors.toList()).toArray(new String[0]);
        fileManageDao.batchUpdateBusinessFile(fileList, projectId);
    }

    @Override
    public void downloadProjectFile(String id, HttpServletResponse response) {
        User currentUser = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        if (ObjectUtils.isEmpty(currentUser)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "用户无权限！");
        }
        FileManage fileManage = fileManageDao.selectById(id);
        if (ObjectUtils.isEmpty(fileManage)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "文件不存在！");
        }
        ExpertProject project = projectDao.selectById(fileManage.getBusinessId());
        if (ObjectUtils.isEmpty(project)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "项目不存在！");
        }
        List<String> allUserList = new ArrayList<>();
        allUserList.add(project.getProjectManager());
        allUserList.addAll(Arrays.asList(project.getProjectMember().split(",")));
        allUserList.addAll(Arrays.asList(project.getAppointedExpert().split(",")));
        allUserList.addAll(Arrays.asList(project.getDivideExpert().split(",")));
        if (allUserList.contains(currentUser.getId())) {

        }
    }

    @Override
    public List<Map<String, Object>> queryExpertInfos(String id) {
        ExpertProject project = projectDao.selectById(id);
        if (ObjectUtils.isEmpty(project)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "项目信息不存在！");
        }
        List<Map<String, Object>> dataList = new ArrayList<>();
        List<String> allExpertList = new ArrayList<>();
        List<String> appointedList = Arrays.asList(project.getAppointedExpert().split(","));
        List<String> divideList = Arrays.asList(project.getDivideExpert().split(","));
        allExpertList.addAll(appointedList);
        allExpertList.addAll(divideList);
        if (ObjectUtils.isEmpty(allExpertList)) {
            return dataList;
        }
        Map<String, Map<String, String>> expertMap = expertDao.getExpertMap();
        for (String expert : allExpertList) {
            if (expertMap.containsKey(expert)) {
                Map<String, String> data = expertMap.get(expert);
                Map<String, Object> memberMap = new HashMap<>();
                memberMap.put("id", data.get("id"));
                memberMap.put("value", data.get("id"));
                memberMap.put("name", data.get("name"));
                memberMap.put("label", data.get("name"));
                dataList.add(memberMap);
            }
        }
        return dataList;
    }

    /**
     * 补全数据
     *
     * @param originList 原始数据
     * @param startNum   起始数
     * @return 补全数据列表
     */
    private List<Map<String, Object>> completeResult(List<ExpertProject> originList, int startNum) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        if (ObjectUtil.isEmpty(originList)) {
            return resultList;
        }
        List<String> projectIdList = originList.stream().map(ExpertProject::getId).collect(Collectors.toList());
        Map<String, Map<String, Object>> difficultyMap = difficultyDao.getDifficultyProcess(projectIdList);
        User currentUser = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        String userId = currentUser.getId();
        List<UserRoleRelation> userRoleRelationList = userRoleRelationDao.queryRelationByUserId(userId);
        UserRole manageRole = roleDao.getRoleBySn("J017");
        List<UserRoleRelation> existList;
        if (ObjectUtils.isEmpty(manageRole)) {
            existList = new ArrayList<>();
        } else {
            existList = userRoleRelationList.stream().filter(relation -> StringUtils.equals(relation.getRoleId(), manageRole.getId())).collect(Collectors.toList());
        }
        boolean defaultPermission = !existList.isEmpty();

        UserRole highRole = roleDao.getRoleBySn("J016");
        List<UserRoleRelation> existHighList;
        if (ObjectUtils.isEmpty(highRole)) {
            existHighList = new ArrayList<>();
        } else {
            existHighList = userRoleRelationList.stream().filter(relation -> StringUtils.equals(relation.getRoleId(), highRole.getId())).collect(Collectors.toList());
        }

        Map<String, Map<String, String>> userMap = userDao.getUserMap();
        Map<String, Map<String, String>> expertMap = expertDao.getExpertMap();
        Map<String, Map<String, String>> departmentMap = departmentDao.getDepartmentMap();
        int sort = startNum + 1;
        for (ExpertProject item : originList) {
            Map<String, Object> map = ObjectUtils.object2Map(item);
            map.put("sort", sort);
            map.put("statusName", DifficultyStatusEnum.getNameByValue(item.getStatus()));
            if (userMap.containsKey(item.getProjectManager())) {
                Map<String, String> projectManagerMap = userMap.get(item.getProjectManager());
                map.put("projectManagerName", projectManagerMap.get("name"));
                map.put("projectManagerContact", projectManagerMap.get("email"));
            } else {
                map.put("projectManagerName", "");
                map.put("projectManagerContact", "");
            }
            map.put("projectLevelName", ExpertProjectLevelEnum.getNameByValue(item.getProjectLevel()));
            map.put("createUserName", userMap.get(item.getCreateUser()).get("name"));
            map.put("expertList", completeExpertList(item, expertMap));
            map.put("departmentName", departmentMap.containsKey(item.getDepartment()) ? departmentMap.get(item.getDepartment()).get("name") : "");
            if (difficultyMap.containsKey(item.getId())) {
                map.put("allNum", difficultyMap.get(item.getId()).get("allNum"));
                map.put("finishNum", difficultyMap.get(item.getId()).get("finishNum"));
            }
            boolean memberPermission = StringUtils.equals(item.getProjectManager(), userId) ||
                    item.getProjectMember().contains(userId);
            boolean expertPermission = item.getAppointedExpert().contains(userId) ||
                    item.getDivideExpert().contains(userId);
            boolean highPermission = !existHighList.isEmpty();
            map.put("checkPermission", defaultPermission || memberPermission || expertPermission || highPermission || item.getStatus() == DifficultyStatusEnum.FINISHED.getValue());
            map.put("modifyPermission", defaultPermission || StringUtils.equals(item.getProjectManager(), userId));
            map.put("expertPermission", defaultPermission || expertPermission);
            map.put("memberPermission", memberPermission);
            map.put("highPermission", highPermission);
            resultList.add(map);
            sort++;
        }
        return resultList;
    }

    private String completeExpertList(ExpertProject project, Map<String, Map<String, String>> expertMap) {
        List<String> expertList = new ArrayList<>();
        List<String> appointedList = StringUtils.isEmpty(project.getAppointedExpert()) ? new ArrayList<>() : Arrays.asList(project.getAppointedExpert().split(","));
        if (!ObjectUtils.isEmpty(appointedList)) {
            expertList.addAll(appointedList);
        }
        List<String> divideList = StringUtils.isEmpty(project.getDivideExpert()) ? new ArrayList<>() : Arrays.asList(project.getDivideExpert().split(","));
        if (!ObjectUtils.isEmpty(divideList)) {
            expertList.addAll(divideList);
        }
        List<String> expertNameList = new ArrayList<>(expertList.size());
        for (String expert : expertList) {
            if (!expertMap.containsKey(expert)) {
                continue;
            }
            expertNameList.add(expertMap.get(expert).get("name"));
        }
        return StringUtils.strip(expertNameList.toString(), "[]");
    }

    private void pushMessage() {
        SystemParameter sp = parameterDao.getParameterByName(SystemConstants.CURRENT_SYSTEM_IP);
        if (ObjectUtils.isEmpty(sp)) {
            throw new AosException(ReturnCodes.HTTP_SYSTEM_ERROR);
        }
    }
}
